package asteroids.model.programs.Statement;

import java.util.ArrayList;

import asteroids.model.Entity;
import asteroids.model.Exception.GlobalVariableException;
import asteroids.model.programs.Program;
import asteroids.model.programs.Type;
import asteroids.model.programs.Expression.VariableLiteral;
import asteroids.model.programs.parsing.ProgramFactory.ForeachType;

/**
* 
* @version 0.3
* @author  Tandan Sunil, Van Deun Luca
*
*/
public class ForEachLiteral extends LoopStatement {

	public ForEachLiteral(int line, int column,
			asteroids.model.programs.parsing.ProgramFactory.ForeachType type,
			String variableName, Statement body) {
		super(line, column, body);
		//TODO: check whether body contains actionStatement
		this.variableName = variableName;
		this.type = type;
	}
	
	private asteroids.model.programs.parsing.ProgramFactory.ForeachType type;
	
	public asteroids.model.programs.parsing.ProgramFactory.ForeachType getType(){
		return type;
	}
	private String variableName;
	public String getVariableName(){
		return variableName;
	}
	
	@Override
	public void execute(Program program) {
		if((program.getVariableOf(getVariableName())==null))
			throw new GlobalVariableException("For Each must have global variable at: \n line: "+this.getLine());
		if(((program.getGlobals().get(getVariableName()))).getType()!= Type.AllType.ENTITY)
			throw new IllegalArgumentException("Variable type mismatch at: \n line: " + this.getLine() +" column: "+this.getColumn());
		ArrayList<Entity> toIterateEntities = new ArrayList<Entity>();
		if(this.getType() == ForeachType.SHIP)
			toIterateEntities = new ArrayList<Entity>(program.getOwner().getWorld().getShips());
		if(this.getType() == ForeachType.BULLET)
			toIterateEntities = new ArrayList<Entity>(program.getOwner().getWorld().getBullets());
		if(this.getType() == ForeachType.ASTEROID)
			toIterateEntities = new ArrayList<Entity>(program.getOwner().getWorld().getAsteroids());
		if(this.getType() == ForeachType.ANY)
			toIterateEntities = new ArrayList<Entity>(program.getOwner().getWorld().getAllEntities());
		VariableLiteral vl = program.getVariableOf(variableName);
		for(Entity e: toIterateEntities){
			getBody().setExecuted(false);
			vl.setEntity(e);
			vl.setType(new Type(Type.AllType.ENTITY));
//			program.changeGlobalVariable(vl);
			getBody().execute(program);
			
		}
		setExecuted(true); //we kunnen het direct op true zetten aangezien er geen actionstatement bevat.
	}

}
